package com.iyao_app.http;

import android.os.Build;
import android.os.Handler;
import android.text.TextUtils;

import com.alibaba.fastjson.JSON;
import com.iyao_app.BuildConfig;
import com.iyao_app.MyApplication;
import com.iyao_app.entry.Result;
import com.iyao_app.entry.ResultModel;
import com.iyaowoqu.base_library.util.AppUtil;
import com.iyaowoqu.base_library.util.JsonFormatUtils;
import com.iyaowoqu.base_library.util.LogUtil;
import com.iyaowoqu.base_library.util.ToastUtils;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.TimeUnit;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.HttpUrl;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

/**
 * 简介 ：
 * 作者 ： hjb
 * 时间 ：2017/11/8.
 */
public class HttpUtil {


    private HttpUtil() {
    }

    private static Handler mHandler = new Handler(MyApplication.getInstance().getMainLooper());
    private static volatile HttpUtil httpUtil;

    public static HttpUtil getIntance() {
        if (httpUtil == null) {
            synchronized (HttpUtil.class) {
                if (httpUtil == null) {
                    httpUtil = new HttpUtil();
                }
            }
        }
        return httpUtil;
    }

    private String getUrl(String url, final HashMap<String, Object> params) {
        // 添加url参数
        if (params != null) {
            Iterator<String> it = params.keySet().iterator();
            StringBuffer sb = null;
            while (it.hasNext()) {
                String key = it.next();
                String value = String.valueOf( params.get(key));
                if (sb == null) {
                    sb = new StringBuffer();
                    sb.append("?");
                } else {
                    sb.append("&");
                }
                sb.append(key);
                sb.append("=");
                sb.append(value);
            }
            if (sb != null)
                url += sb.toString();
        }
        return url;
    }

    public void get(final String url, final HashMap<String, Object> params, final NetCallBack callback, @SuppressWarnings("rawtypes") final Class type) {

        String finalUrl = getUrl(url, params);
        LogUtil.e("==GET请求链接==>:" + url + "\t\n==请求参数==>:\t\n" + finalUrl);
        // 网络是否可用
        if (AppUtil.isNetworkConnected(MyApplication.getInstance())) {

//            MediaType JSON = MediaType.parse("application/json; charset=utf-8");

            Request request = new Request.Builder()
                    .url(finalUrl)
                    .build();
            requestService(request, callback, type);
        } else {
            ToastUtils.showShort("当前网络不可用,请检查网络连接");
            callback.onFail("网络不可用", 444);
        }
    }

    public void post(final String url, final HashMap<String, Object> params, final NetCallBack callback, @SuppressWarnings("rawtypes") final Class type) {
        String json = JSON.toJSONString(params, false);
        LogUtil.e("==POST请求链接==>:" + url + "\t\n==请求参数==>:\t\n" + json);
        // 网络是否可用
        if (AppUtil.isNetworkConnected(MyApplication.getInstance())) {

            MediaType JSON = MediaType.parse("application/json; charset=utf-8");
            RequestBody body = RequestBody.create(JSON, json);
            Request request = new Request.Builder()
                    .url(url)
                    .header("Content-Type", "application/json; charset=utf-8")
                    .addHeader("Connection", "close")
                    .post(body)
                    .build();

            requestService(request, callback, type);

        } else {
            ToastUtils.showShort("当前网络不可用,请检查网络连接");
            callback.onFail("网络不可用", 444);
        }

    }


    private void requestService(Request request, final NetCallBack callback, @SuppressWarnings("rawtypes") final Class type) {

        OkUtil.getOkHttpClient()
                .newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(final Call call, final IOException e) {
                handleError(call, callback, e);
                if (BuildConfig.DEBUG) {
                    LogUtil.e("==onFailure==call==>" + call.request().toString());
                }
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                try {
                    final String string = response.body().string();
                    handleResponse(string, call, response, callback, type);
                    if (BuildConfig.DEBUG) {
                        LogUtil.e("请求url:\n" + call.request().url() + "\n返回数据:\n" + JsonFormatUtils.formatJson(string));
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                    mHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            callback.onFail("no data", 0);
                        }
                    });
                }
            }
        });
    }

    public void upLoadFile(String actionUrl, HashMap<String, Object> paramsMap, final NetCallBack callback, @SuppressWarnings("rawtypes") final Class type) {
        try {

            MultipartBody.Builder builder = new MultipartBody.Builder();
            //设置类型
            builder.setType(MultipartBody.FORM);
            //追加参数
            for (String key : paramsMap.keySet()) {
                Object object = paramsMap.get(key);
                if (!(object instanceof File)) {
                    builder.addFormDataPart(key, object.toString());
                } else {
                    File file = (File) object;
                    builder.addFormDataPart(key, file.getName(), RequestBody.create(null, file));
                }
            }
            //创建RequestBody
            RequestBody body = builder.build();
            //创建Request
            final Request request = new Request.Builder().url(actionUrl).post(body).build();
            //单独设置参数 比如读取超时时间
            final Call call = OkUtil.getOkHttpClient().newBuilder().writeTimeout(50, TimeUnit.SECONDS).build().newCall(request);
            call.enqueue(new Callback() {
                @Override
                public void onFailure(Call call, IOException e) {
                    handleError(call, callback, e);
                    if (BuildConfig.DEBUG) {
                        LogUtil.e("==onFailure==call==>" + call.request().toString());
                    }
                }

                @Override
                public void onResponse(Call call, Response response) throws IOException {
                    try {
                        final String string = response.body().string();
                        handleResponse(string, call, response, callback, type);
                        if (BuildConfig.DEBUG) {
                            LogUtil.e("请求url:\n" + call.request().url() + "\n返回数据:\n" + JsonFormatUtils.formatJson(string));
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                        mHandler.post(new Runnable() {
                            @Override
                            public void run() {
                                callback.onFail("no data", 0);
                            }
                        });
                    }
                }
            });
        } catch (Exception e) {
            callback.onFail("解析异常", 1000);
        }
    }

    private void handleResponse(final String s, Call call, final Response response, final NetCallBack callback, @SuppressWarnings("rawtypes") final Class type) {
        LogUtil.e("=====handleResponse======");
        if (response.isSuccessful()) {
            LogUtil.e("=====isSuccessful======");
            if (callback != null) {
                LogUtil.e("=====callback======");
                final Result result = JSON.parseObject(s, Result.class);
                if (null != type) {
                    LogUtil.e("=====type======");
                    final ResultModel body = new ResultModel();
                    // 判断是jsonObject 还是 jsonArray
                    String data = result.getData();
                    if (data != null) {
                        if (isJsonArray(result.getData())) {
                            List<?> ls = JSON.parseArray(result.getData(), type);
                            body.setModelList(ls);
                        } else {
                            body.setModel(JSON.parseObject(result.getData(), type));
                        }
                        LogUtil.e("=====data======");
                        mHandler.post(new Runnable() {
                            @Override
                            public void run() {
                                callback.onSuccess(result.getMessage(), result.getCode(), s, body);
                            }
                        });
                    } else {
                        LogUtil.e("=====result.getData() = null======");
                        mHandler.post(new Runnable() {
                            @Override
                            public void run() {
                                callback.onSuccess(result.getMessage(), result.getCode(), s, null);
                            }
                        });
                    }
                } else {
                    mHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            callback.onSuccess(result.getMessage(), result.getCode(), s, null);
                        }
                    });
                }
            }
        }else {
            if (callback != null) {
                callback.onFail("请求异常", response.code());
                LogUtil.e("=====r服务器异常 = null======"+response.code());
            }
        }
    }

    private void handleError(Call call, final NetCallBack callback, final Exception ex) {
        if (callback != null) {
            mHandler.post(new Runnable() {
                @Override
                public void run() {
                    // onFailure(e);
                    if (callback != null) {
                        callback.onFail("服务器异常", 500);

                    }
                    String msg = ex.getMessage();
                    if (BuildConfig.DEBUG) {
                        LogUtil.e("==失败==Exception==>" + msg);
                    }
                }
            });

        }
    }

    /**
     * 判断是否是json数组
     *
     * @param str
     * @return
     */
    public boolean isJsonArray(String str) {
        final char[] strChar = str.substring(0, 1).toCharArray();
        final char firstChar = strChar[0];
        return firstChar == '[';
    }
}
